home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / aros / filesys / nil_handler.c < prev    next >
C/C++ Source or Header  |  1996-09-12  |  7KB  |  314 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: nil_handler.c,v 1.3 1996/08/13 15:35:07 digulla Exp $
  4.     $Log: nil_handler.c,v $
  5.     Revision 1.3  1996/08/13 15:35:07  digulla
  6.     Replaced __AROS_LA by __AROS_LHA
  7.  
  8.     Revision 1.2  1996/08/01 17:41:23  digulla
  9.     Added standard header for all files
  10.  
  11.     Desc:
  12.     Lang:
  13. */
  14. #include <exec/resident.h>
  15. #include <exec/memory.h>
  16. #include <clib/exec_protos.h>
  17. #include <utility/tagitem.h>
  18. #include <dos/dosextens.h>
  19. #include <dos/filesystem.h>
  20. #include <clib/dos_protos.h>
  21. #include <aros/libcall.h>
  22. #ifdef __GNUC__
  23.     #include "nil_handler_gcc.h"
  24. #endif
  25.  
  26. static const char name[];
  27. static const char version[];
  28. static const APTR inittabl[4];
  29. static void *const functable[];
  30. struct nilbase *nil_handler_init();
  31. void nil_handler_open();
  32. BPTR nil_handler_close();
  33. BPTR nil_handler_expunge();
  34. int nil_handler_null();
  35. void nil_handler_beginio();
  36. LONG nil_handler_abortio();
  37. static const char end;
  38.  
  39. struct device
  40. {
  41.     struct DosList *doslist;
  42.     ULONG usecount;
  43. };
  44.  
  45. int nil_handler_entry(void)
  46. {
  47.     /* If the handler was executed by accident return error code. */
  48.     return -1;
  49. }
  50.  
  51. const struct Resident nil_handler_resident=
  52. {
  53.     RTC_MATCHWORD,
  54.     (struct Resident *)&nil_handler_resident,
  55.     (APTR)&end,
  56.     RTF_AUTOINIT,
  57.     1,
  58.     NT_DEVICE,
  59.     0,
  60.     (char *)name,
  61.     (char *)&version[6],
  62.     (ULONG *)inittabl
  63. };
  64.  
  65. static const char name[]="nil.handler";
  66.  
  67. static const char version[]="$VER: nil_handler 1.0 (8.6.96)\n\015";
  68.  
  69. static const APTR inittabl[4]=
  70. {
  71.     (APTR)sizeof(struct nilbase),
  72.     (APTR)functable,
  73.     NULL,
  74.     &nil_handler_init
  75. };
  76.  
  77. static void *const functable[]=
  78. {
  79.     &nil_handler_open,
  80.     &nil_handler_close,
  81.     &nil_handler_expunge,
  82.     &nil_handler_null,
  83.     &nil_handler_beginio,
  84.     &nil_handler_abortio,
  85.     (void *)-1
  86. };
  87.  
  88. __AROS_LH2(struct nilbase *, init,
  89.  __AROS_LHA(struct nilbase *, nilbase, D0),
  90.  __AROS_LHA(BPTR,             segList, A0),
  91.        struct ExecBase *, sysBase, 0, nil_handler)
  92. {
  93.     __AROS_FUNC_INIT
  94.  
  95.     /* Store arguments */
  96.     nilbase->sysbase=sysBase;
  97.     nilbase->seglist=segList;
  98.     nilbase->dosbase=(struct DosLibrary *)OpenLibrary("dos.library",39);
  99.     if(nilbase->dosbase!=NULL)
  100.     return nilbase;
  101.  
  102.     return NULL;
  103.     __AROS_FUNC_EXIT
  104. }
  105.  
  106. __AROS_LH3(void, open,
  107.  __AROS_LHA(struct IOFileSys *, iofs, A1),
  108.  __AROS_LHA(ULONG,              unitnum, D0),
  109.  __AROS_LHA(ULONG,              flags, D0),
  110.        struct nilbase *, nilbase, 1, nil_handler)
  111. {
  112.     __AROS_FUNC_INIT
  113.  
  114.     /* Keep compiler happy */
  115.     unitnum=0;
  116.     flags=0;
  117.  
  118.     /* I have one more opener. */
  119.     nilbase->device.dd_Library.lib_OpenCnt++;
  120.     nilbase->device.dd_Library.lib_Flags&=~LIBF_DELEXP;
  121.  
  122.     /* Set returncode */
  123.     iofs->IOFS.io_Error=0;
  124.  
  125.     /* Mark Message as recently used. */
  126.     iofs->IOFS.io_Message.mn_Node.ln_Type=NT_REPLYMSG;
  127.     __AROS_FUNC_EXIT
  128. }
  129.  
  130. __AROS_LH1(BPTR, close,
  131.  __AROS_LHA(struct IOFileSys *, iofs, A1),
  132.        struct nilbase *, nilbase, 2, nil_handler)
  133. {
  134.     __AROS_FUNC_INIT
  135.  
  136.     /* Let any following attemps to use the device crash hard. */
  137.     iofs->IOFS.io_Device=(struct Device *)-1;
  138.  
  139.     /* I have one fewer opener. */
  140.     if(!--nilbase->device.dd_Library.lib_OpenCnt)
  141.     {
  142.     /* Delayed expunge pending? */
  143.     if(nilbase->device.dd_Library.lib_Flags&LIBF_DELEXP)
  144.         /* Then expunge the device */
  145.         return expunge();
  146.     }
  147.     return 0;
  148.     __AROS_FUNC_EXIT
  149. }
  150.  
  151. __AROS_LH0(BPTR, expunge, struct nilbase *, nilbase, 3, nil_handler)
  152. {
  153.     __AROS_FUNC_INIT
  154.  
  155.     BPTR ret;
  156.     /*
  157.     This function is single-threaded by exec by calling Forbid.
  158.     Never break the Forbid() or strange things might happen.
  159.     */
  160.  
  161.     /* Test for openers. */
  162.     if(nilbase->device.dd_Library.lib_OpenCnt)
  163.     {
  164.     /* Set the delayed expunge flag and return. */
  165.     nilbase->device.dd_Library.lib_Flags|=LIBF_DELEXP;
  166.     return 0;
  167.     }
  168.  
  169.     /* Free all resources */
  170.     CloseLibrary((struct Library *)nilbase->dosbase);
  171.  
  172.     /* Get rid of the device. Remove it from the list. */
  173.     Remove(&nilbase->device.dd_Library.lib_Node);
  174.  
  175.     /* Get returncode here - FreeMem() will destroy the field. */
  176.     ret=nilbase->seglist;
  177.  
  178.     /* Free the memory. */
  179.     FreeMem((char *)nilbase-nilbase->device.dd_Library.lib_NegSize,
  180.         nilbase->device.dd_Library.lib_NegSize+nilbase->device.dd_Library.lib_PosSize);
  181.  
  182.     return ret;
  183.     __AROS_FUNC_EXIT
  184. }
  185.  
  186. __AROS_LH0I(int, null, struct nilbase *, nilbase, 4, nil_handler)
  187. {
  188.     __AROS_FUNC_INIT
  189.     return 0;
  190.     __AROS_FUNC_EXIT
  191. }
  192.  
  193. __AROS_LH1(void, beginio,
  194.  __AROS_LHA(struct IOFileSys *, iofs, A1),
  195.        struct nilbase *, nilbase, 5, nil_handler)
  196. {
  197.     __AROS_FUNC_INIT
  198.     LONG error=0;
  199.     struct device *dev;
  200.     struct DosList *dl;
  201.  
  202.     /*
  203.     Do everything quick no matter what. This is possible
  204.     because I never need to Wait().
  205.     */
  206.     switch(iofs->IOFS.io_Command)
  207.     {
  208.     case FSA_STARTUP:
  209.         /* AddDosEntry() may Wait(), so return error code if necessary */
  210.         if(!(iofs->IOFS.io_Flags&IOF_QUICK))
  211.         {
  212.         error=ERROR_NOT_IMPLEMENTED;
  213.         break;
  214.         }
  215.         dev=AllocMem(sizeof(struct device),MEMF_PUBLIC|MEMF_CLEAR);
  216.         if(dev!=NULL)
  217.         {
  218.         dl=MakeDosEntry((STRPTR)iofs->io_Args[0],DLT_DEVICE);
  219.         if(dl==NULL)
  220.         {
  221.             dl->dol_Unit=(struct Unit *)dev;
  222.             dl->dol_Device=&nilbase->device;
  223.             dev->doslist=dl;
  224.             if(AddDosEntry(dl))
  225.             break;
  226.             else
  227.             error=ERROR_OBJECT_EXISTS;
  228.             FreeDosEntry(dl);
  229.         }else
  230.             error=ERROR_NO_FREE_STORE;
  231.         FreeMem(dev,sizeof(struct device));
  232.         }
  233.         else
  234.         error=ERROR_NO_FREE_STORE;
  235.         break;
  236.  
  237.     case FSA_DIE:
  238.         /* RemDosEntry() may wait, so return error code if necessary */
  239.         if(!(iofs->IOFS.io_Flags&IOF_QUICK))
  240.         {
  241.         error=ERROR_NOT_IMPLEMENTED;
  242.         break;
  243.         }
  244.         LockDosList(LDF_DEVICES|LDF_WRITE);
  245.         dev=(struct device *)iofs->io_Args[0];
  246.         if(dev->usecount==1)
  247.         {
  248.         RemDosEntry(dev->doslist);
  249.         FreeDosEntry(dev->doslist);
  250.         FreeMem(dev,sizeof(struct device));
  251.         }else
  252.         {
  253.         Disable();
  254.         dev->usecount--;
  255.         Enable();
  256.         error=ERROR_OBJECT_IN_USE;
  257.         }
  258.         UnLockDosList(LDF_DEVICES|LDF_WRITE);
  259.         break;
  260.  
  261.     case FSA_LOCATE_OBJECT:
  262.         /* No names allowed on NIL: */
  263.         if(((STRPTR)iofs->io_Args[0])[0])
  264.         {
  265.         error=ERROR_OBJECT_NOT_FOUND;
  266.         break;
  267.         }
  268.         Disable();
  269.         ((struct device *)iofs->IOFS.io_Unit)->usecount++;
  270.         Enable();
  271.         break;
  272.  
  273.     case FSA_READ:
  274.         iofs->io_Args[1]=0;
  275.         break;
  276.  
  277.     case FSA_WRITE:
  278.         break;
  279.  
  280.     case FSA_SEEK:
  281.         iofs->io_Args[0]=0;
  282.         iofs->io_Args[1]=0;
  283.         break;
  284.  
  285.     case FSA_FREE_LOCK:
  286.         break;
  287.  
  288.     default:
  289.         error=ERROR_NOT_IMPLEMENTED;
  290.         break;
  291.     }
  292.  
  293.     /* Set error code */
  294.     iofs->io_DosError=error;
  295.  
  296.     /* If the quick bit is not set send the message to the port */
  297.     if(!(iofs->IOFS.io_Flags&IOF_QUICK))
  298.     ReplyMsg(&iofs->IOFS.io_Message);
  299.  
  300.     __AROS_FUNC_EXIT
  301. }
  302.  
  303. __AROS_LH1(LONG, abortio,
  304.  __AROS_LHA(struct IOFileSys *, iofs, A1),
  305.        struct nilbase *, nilbase, 6, nil_handler)
  306. {
  307.     __AROS_FUNC_INIT
  308.     /* Everything already done. */
  309.     return 0;
  310.     __AROS_FUNC_EXIT
  311. }
  312.  
  313. static const char end=0;
  314.